<?php

/**
 * Model che rappresenta un agente nel DB.
 */
class VariazioneArticoloOfferta extends StdModel
{

	private static $singleton = NULL;

	/**
	 * Ritorna una istanza globale di questo model.
	 * @return mixed La istanza globale.
	 */
	public static function getInstance()
	{
		if(self::$singleton == NULL)
			self::$singleton = new VariazioneArticoloOfferta();
		return self::$singleton;
	}

	/*
	 * Specifiche attributi del tipo del Model rappresentato da questa classe
	 */
	public $attribTableName = "VariazioneArticoloOfferta";
	public $attribLabel = array("idOfferta", "idVariazioneArticolo");
	public $attribNames = array(STD_ID, "idOfferta", "idVariazioneArticolo", "PrezzoNetto", "Quantita", "Totale");
	public $attribExcludeFromAdd = array(STD_ID);
	public $attribExcludeFromEdit = array(STD_ID, "idOfferta", "idVariazioneArticolo");
	public $attribLongNames = array(STD_ID => "ID", "IdOfferta" => "Offerta", "idVariazioneArticolo" => "Variazione articolo",
		"PrezzoNetto" => "Prezzo netto &euro;", "Quantita" => "Quantit&agrave;", "Totale" => "Totale &euro;");
	public $attribIsImportant = array(STD_ID => 2, "idOfferta" => 1, "idVariazioneArticolo" => 1,
		"PrezzoNetto" => 1, "Quantita" => 1, "Totale" => 1);
	public $attribIsNumeric = array(STD_ID => true, "idOfferta" => true, "idVariazioneArticolo" => true,
		"PrezzoNetto" => true, "Quantita" => true, "Totale" => true);
	public $attribIsForeignKey = array(STD_ID => false, "idOfferta" => "Offerte", "idVariazioneArticolo" => "Variazioni Articoli",
		"PrezzoNetto" => false, "Quantita" => false, "Totale" => false);

	/*
	 * Specifiche per gli elementi form associati agli attributi
	 */
	private static $attribHTMLFormValue = array(STD_ID => FORM_HIDDEN, "idOfferta" => FORM_HIDDEN, "idVariazioneArticolo" => FORM_EXTERNAL_SELECTOR,
		"PrezzoNetto" => FORM_TEXT, "Quantita" => FORM_TEXT, "Totale" => FORM_TEXT);
	private static $attribHTMLFormIsMandatory = array(STD_ID => true, "idOfferta" => true, "idVariazioneArticolo" => true,
		"PrezzoNetto" => true, "Quantita" => true, "Totale" => true);

	/**
	 * Restituisce l'HTML per creare un campo di un form adatto a contenere il
	 * valore dell'attribbuto passato. Questo campo di testo sarà vuoto e dovrà
	 * servire per la creazione di una nuova istanza in DB di questo model.
	 * @param string $attribName Nome dell'attributo su cui creare il campo.
	 * @return string Stringa contenente l'HTML dell'elemento creato.
	 */
	public function getAddFormCodeFromAttribute($db,$attribName)
	{
		if(!isset(self::$attribHTMLFormValue[$attribName]) || $attribName == STD_ID || $attribName == "Totale")
			return "";
		$defval = NULL;
		if($attribName == "PrezzoDiListino")
			$defval = "0.0";
		elseif($attribName == "QuantitaListino")
			$defval = "1";
		switch(self::$attribHTMLFormValue[$attribName])
		{
			case FORM_TEXT: return ModelUtils::getTextFormElement($attribName, $defval, self::$attribHTMLFormIsMandatory[$attribName], 0);
			case FORM_HIDDEN: return ModelUtils::getHiddenFormElement($attribName, isset($this->dataTupla[$attribName]) && $this->dataTupla[$attribName] != NULL ? $this->dataTupla[$attribName] : "", self::$attribHTMLFormIsMandatory[$attribName]);
			case FORM_NUMERIC: return ModelUtils::getNumericFormElement($attribName, "1", "1", NULL, self::$attribHTMLFormIsMandatory[$attribName], 0);
			case FORM_EXTERNAL_SELECTOR:
			{
				$condParam = "";
				$condValue = "";
				if($this->chachedArticolo != null)
				{
					$condParam = "idArticolo";
					$condValue = $this->chachedArticolo->dataTupla[STD_ID];
				}
				return ModelUtils::getExternalSelectorFormElement($attribName, "externalSelector.php", "VariazioneArticolo", "", "",
						self::$attribHTMLFormIsMandatory[$attribName],
						array("PrezzoNetto" => "PrezzoDiListino", "Quantita" => "QuantitaListino"),
						$condParam, $condValue);
			}
			default: return "";
		}
	}

	/**
	 * Restituisce l'HTML per creare un campo di testo adatto a contenere il
	 * valore dell'attribbuto passato. Questo campo di testo conterrà il valore
	 * attualmente assunto da questo attributo in questa tupla.
	 * @param DatabaseManager $db Database su cui effettuare una possibile
	 * interrogazione.
	 * @param string $attribName Nome dell'attributo di cui creare il codice.
	 * @return string Il codice HTML dell'elemento form corrispondente.
	 */
	public function getEditFormCodeFromAttribute($db, $attribName)
	{
		if(!isset(self::$attribHTMLFormValue[$attribName]))
			return "";
		$other = "";
		if($attribName == "PrezzoNetto" || $attribName == "Quantita")
		{
			$other = 'onchange="document.getElementsByName(\'Totale\')[0].value=(document.getElementsByName(\'PrezzoNetto\')[0].value*document.getElementsByName(\'Quantita\')[0].value);"';
		}
		elseif($attribName == "Totale")
		{
			$other = 'readonly';
		}
		switch(self::$attribHTMLFormValue[$attribName])
		{
			case FORM_TEXT: return ModelUtils::getTextFormElement($attribName, $this->dataTupla[$attribName], self::$attribHTMLFormIsMandatory[$attribName], 0, $other);
			case FORM_HIDDEN: return ModelUtils::getHiddenFormElement($attribName, isset($this->dataTupla[$attribName]) && $this->dataTupla[$attribName] != NULL ? $this->dataTupla[$attribName] : "", self::$attribHTMLFormIsMandatory[$attribName]);
			case FORM_NUMERIC: return ModelUtils::getNumericFormElement($attribName, $this->dataTupla[$attribName], "1", NULL, self::$attribHTMLFormIsMandatory[$attribName], 0, $other);
			default: return "";
		}
	}

	/**
	 * Aggiungi i valori di questa istanza al DB. L'ID di questa istanza
	 * assumerà il valore della chiave primaria della tupla appena inserita nel
	 * DB.
	 * @param DatabaseManager $db Database su cui effettuare l'INSERT.
	 * @return boolean Restituisce vero se l'INSERT è andato a buon fine, falso
	 * altrimenti.
	 */
	public function addToDB($db)
	{
		$this->dataTupla["Totale"] = (float)$this->dataTupla["PrezzoNetto"]*(float)$this->dataTupla["Quantita"];
		return parent::addToDB($db);
	}

	/**
	 * Costruttore che acquisisce l'array dei valori associativi.
	 * @param type $data L'array associativo a cui inizializzare questa istanza.
	 */
	public function __construct($data = NULL)
	{
		parent::__construct($data);
	}

	/**
	 * Crea una nuova istanza della sottoclasse specializzante.
	 * @param array $data I dati passati da cui recuperare i valori.
	 * @return mixed Una nuova instanza della sottoclasse specializzante.
	 */
	public function createNew($data)
	{
		$res = new VariazioneArticoloOfferta($data);
		return $res;
	}
	
	/**
	 * Duplica tutte le tuple di questo model con l'id offerta specificato
	 * ed imposta nelle nuove tuple come id offerta il valore idOfferta passato.
	 * @param DatabaseManager $db Database da interrogare.
	 * @param int $idVecchiaOfferta ID vecchia offerta delle tuple da duplicare.
	 * @param int $idNuovaOfferta ID nuova offerta da impostare nelle nuove tuple.
	 */
	public function duplicateFromIDOfferta($db,$idVecchiaOfferta,$idNuovaOfferta)
	{
		return $db->AddRecordsWithSELECT($this->attribTableName, "idVariazioneArticolo, idOfferta, PrezzoNetto, Quantita, Totale",
				"SELECT idVariazioneArticolo, ".$idNuovaOfferta.", PrezzoNetto, Quantita, Totale FROM ".$this->attribTableName." WHERE idOfferta = ".$idVecchiaOfferta);
	}

	const getOfferteJoinTable  = "VariazioneArticoloOfferta LEFT JOIN Offerta ON VariazioneArticoloOfferta.idOfferta = Offerta.ID";
	const getOfferteJoinSelect = "Offerta.*, VariazioneArticoloOfferta.ID AS IDAssoc, idVariazioneArticolo, idOfferta, PrezzoNetto, Quantita, Totale";

	public $chachedOfferta = NULL;

	const getVariazioneArticoloJoinTable  = "VariazioneArticoloOfferta LEFT JOIN VariazioneArticolo ON VariazioneArticoloOfferta.idVariazioneArticolo = VariazioneArticolo.ID";
	const getVariazioneArticoloJoinSelect = "VariazioneArticolo.*, VariazioneArticoloOfferta.ID AS IDAssoc, idVariazioneArticolo, idOfferta, PrezzoNetto, Quantita, Totale";

	public $chachedVariazioneArticolo = NULL;

	public $chachedArticolo = NULL;

	/**
	 * Crea una nuova istanza della sottoclasse specializzante.
	 * @param array $data I dati passati da cui recuperare i valori.
	 * @return mixed Una nuova instanza della sottoclasse specializzante.
	 */
	public function createNewWithVariazioneArticolo($data)
	{
		$cc = VariazioneArticolo::getInstance()->createNew($data);
		$data[STD_ID] = $data["IDAssoc"];
		$newinstance = $this->createNew($data);
		$newinstance->chachedVariazioneArticolo = $cc;
		return $newinstance;
	}

	/**
	 * Crea una nuova istanza della sottoclasse specializzante.
	 * @param array $data I dati passati da cui recuperare i valori.
	 * @return mixed Una nuova instanza della sottoclasse specializzante.
	 */
	public function createNewWithOfferta($data)
	{
		$co = Offerta::getInstance()->createNew($data);
		$data[STD_ID] = $data["IDAssoc"];
		$newinstance = $this->createNew($data);
		$newinstance->chachedOfferta = $co;
		return $newinstance;
	}

	/**
	 * Restituisce una lista di associazioni di offerte di un dato articolo.
	 * @param DatabaseManager $db Database da interrogare.
	 * @param int $idVariazioneArticolo Id variazione articolo di cui restituire
	 * le offerte associate.
	 * @return array L'array di elementi trovati o NULL in caso di errore.
	 */
	public function getListFromDBByIDVariazioneArticolo($db, $idVariazioneArticolo)
	{
		$rs = $db->EnumerateTableStartExt(self::getOfferteJoinSelect,self::getOfferteJoinTable,"","idVariazioneArticolo = ".$idVariazioneArticolo,"");
		if($rs == FALSE)
			return NULL;
		$retarr = array();
		while($db->EnumerateTableNext($rs))
			$retarr[] = $this->createNewWithOfferta($db->EnumerateTableGetValues($rs));
		return $retarr;
	}

	/**
	 * Restituisce una lista di associazioni di articoli di una data offerta.
	 * @param DatabaseManager $db Database da interrogare.
	 * @param int $idOfferta Id offerta di cui restituire i clienti associati.
	 * @return array L'array di elementi trovati o NULL in caso di errore.
	 */
	public function getListFromDBByIDOfferta($db, $idOfferta)
	{
		$rs = $db->EnumerateTableStartExt(self::getVariazioneArticoloJoinSelect,self::getVariazioneArticoloJoinTable,"","idOfferta = ".$idOfferta,"");
		if($rs == FALSE)
			return NULL;
		$retarr = array();
		while($db->EnumerateTableNext($rs))
			$retarr[] = $this->createNewWithVariazioneArticolo($db->EnumerateTableGetValues($rs));
		return $retarr;
	}

	/**
	 * Ritorna una istanza di VariazioneArticolo corrispondente alla chiave esterna
	 * "idVariazioneArticolo" di questa tupla.
	 * @param DatabaseManager $db Database da interrogare.
	 * @return VariazioneArticolo L'instanza creata o NULL in caso di errore.
	 */
	public function getVariazioneArticolo($db)
	{
		$idag = isset($this->dataTupla["idVariazioneArticolo"]) ? $this->dataTupla["idVariazioneArticolo"] : NULL;
		if($idag != NULL && $idag > 0)
		{
			if($this->chachedVariazioneArticolo == NULL || $this->chachedVariazioneArticolo->dataTupla[STD_ID] != $idag)
			{
				$this->chachedVariazioneArticolo = VariazioneArticolo::getInstance()->getFromDB($db, $this->dataTupla["idVariazioneArticolo"]);
				return $this->chachedVariazioneArticolo;
			}
			else
				return $this->chachedVariazioneArticolo;
		}
		return NULL;
	}

	/**
	 * Ritorna una istanza di Offerta corrispondente alla chiave esterna
	 * "idOfferta" di questa tupla.
	 * @param DatabaseManager $db Database da interrogare.
	 * @return Offerta L'instanza creata o NULL in caso di errore.
	 */
	public function getOfferta($db)
	{
		$idag = isset($this->dataTupla["idOfferta"]) ? $this->dataTupla["idOfferta"] : NULL;
		if($idag != NULL && $idag > 0)
		{
			if($this->chachedOfferta == NULL || $this->chachedOfferta->dataTupla[STD_ID] != $idag)
			{
				$this->chachedOfferta = Offerta::getInstance()->getFromDB($db, $this->dataTupla["idOfferta"]);
				return $this->chachedOfferta;
			}
			else
				return $this->chachedOfferta;
		}
		return NULL;
	}

	private static $assocAttribLongNames = array(STD_ID => "ID", "Codice" => "Codice", "DettagliTecnici" => "Dettagli tecnici",
		"PrezzoNetto" => "Prezzo netto &euro;", "Quantita" => "Quantit&agrave;", "Totale" => "Totale &euro;");

	/**
	 * Restituisce gli attributi che danno maggiori informazioni di questa tupla
	 * come ad esempio gli attributi di un oggetto specificato da una chiave
	 * esterna.
	 * @return array L'array esteso di nomi di attributi.
	 */
	public function getExtendedInfoAttributeLongNames()
	{
		return self::$assocAttribLongNames;
	}

	/**
	 * Metodo che restituisce una etichetta che rappresenta il valore di un
	 * attributo: nella sua versione di default ritorna esattamente il valore
	 * associato a quell'attributo, ma è possibile implementarlo nelle
	 * sottoclassi per specificare opportuni comportamenti, come ad esempio di
	 * non far stampare un numero che rappresenta una chiave esterna, ma invece
	 * una etichetta della tupla ad essa associata.
	 * @param DatabaseManager $db Database su cui poter effettuare una possibile
	 * interrogazione.
	 * @param string $attrib Attributo di cui stampare l'etichetta del valore.
	 * @return string Il valore associato all'attributo o NULL se l'attributo
	 * non è stato trovato.
	 */
	public function getDataLabel($db, $attrib)
	{
		if(isset($this->dataTupla[$attrib]) && ($attrib != STD_ID || $this->showRealValues_Enabled))
			return $this->dataTupla[$attrib];
		else
		{
			$varArt = $this->getVariazioneArticolo($db);
			$varArt->cutLongStrings($this->cutDataLabels);
			return $varArt->getDataLabel($db, $attrib);
		}
	}

	/**
	 * Imposta una flag che determina se tagliare le stringhe lunghe o meno
	 * quando restituite con il metodo getDataLabel().
	 * @param boolean $enabled Se abilitare o meno la flag.
	 */
	public function cutLongStrings($enabled)
	{
		$this->cutDataLabels = $enabled;
		if($this->chachedVariazioneArticolo != NULL)
			$this->chachedVariazioneArticolo->cutLongStrings($enabled);
	}

}

?>
